package com.bestcem.xm.ticket.controller.v2;

import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.util.StrUtil;
import com.bestcem.xm.common.core.constant.RegTypes;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.component.security.dto.TokenDTO;
import com.bestcem.xm.ticket.constant.Constants;
import com.bestcem.xm.ticket.controller.param.FollowTicketParam;
import com.bestcem.xm.ticket.controller.param.ReopenTicketParam;
import com.bestcem.xm.ticket.controller.param.SimpleSimpleTicketIdParam;
import com.bestcem.xm.ticket.controller.param.ticket.InsertTicketParam;
import com.bestcem.xm.ticket.controller.param.ticket.TransferTicketParam;
import com.bestcem.xm.ticket.controller.vo.SimpleIdVO;
import com.bestcem.xm.ticket.enums.FollowerFilterEnum;
import com.bestcem.xm.ticket.grpc.client.TicketBaseUserGrpcService;
import com.bestcem.xm.ticket.grpc.client.TicketUserGrpcService;
import com.bestcem.xm.ticket.grpc.client.dto.user.GroupDTO;
import com.bestcem.xm.ticket.service.TicketOperateService;
import com.bestcem.xm.ticket.service.TicketService;
import com.bestcem.xm.ticket.service.dto.ticket.CloseTicketDTO;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 工单的各类操作
 * 手动创建/转派/关闭/重新打开/跟进
 *
 * @author ympan <yuming.pan@idiaoyan.com>
 * @author 2021/12/7 14:55  XiaoYunSong <ys.xiao@idiaoyan.com> 接口移动, 工单相关的操作统一到这个 controller
 * @version dingtalk
 * @date 2021/9/2 18:24
 */
@Slf4j
@RestController(value = "TicketV2TicketController")
@RequestMapping(value = "/ticket/v2/ticket", produces = MediaType.APPLICATION_JSON_VALUE)
public class TicketController {

    @Resource
    private HttpServletRequest request;

    @Resource
    private TicketService ticketService;
    @Resource
    private TicketOperateService ticketOperateService;

    @Resource
    private TicketUserGrpcService ticketUserGrpcService;
    @Resource
    private TicketBaseUserGrpcService ticketBaseUserGrpcService;

    
    /**
     * 创建工单
     */
    @PostMapping(value = "/")
    public XmResultJson<SimpleIdVO> insertTicket(@RequestBody InsertTicketParam param) {
        
        
        
        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        String userName = "";
        if (Objects.nonNull(tokenDTO)) {
            userName = tokenDTO.getRealName();
        }
        param.setOrgId(orgId);
        param.setUserId(userId);
        param.setUsername(userName);
        ServiceResult<SimpleIdVO> serviceResult = ticketOperateService.createTicket(param);
        if (serviceResult.isSuccess()) {
            return XmResultJson.success(serviceResult.getData());
        }
        return XmResultJson.fail(serviceResult.getErrorData(), serviceResult.getMsg());
    }


    /**
     * 跟进工单
     *
     * @param param 前端传来的跟进参数
     * @return com.bestcem.xm.util.XmResultJson<com.bestcem.xm.ticket.controller.vo.SimpleIdVO> 工单id
     * @author zq.ding <zq.ding@idiaoyan.com>
     * @date 2021/9/2 11:48
     */
    @PostMapping(value = "/follow")
    public XmResultJson<SimpleIdVO> followed(@RequestBody FollowTicketParam param) {
        
        
        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        TokenDTO tokenDTO = SecurityContextHolder.getToken();

        param.setOrgId(orgId);
        // 初始化用户id和用户名、组织名
        param.setUserId(userId);
        param.setUserName("");
        param.setOrgCode("");
        // 根据token里的值更新用户id和用户名、组织名
        if (StrUtil.isNotEmpty(tokenDTO.getRealName())) {
            param.setUserName(tokenDTO.getRealName());
        }
        if (StrUtil.isNotEmpty(tokenDTO.getOrgCode())) {
            param.setOrgCode(tokenDTO.getOrgCode());
        }
        if (!ObjectId.isValid(param.getTicketId())) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "缺少必要参数");
        }

        ServiceResult<String> result = ticketOperateService.followTicket(param);
        if (result.isSuccess()) {
            return XmResultJson.success(new SimpleIdVO(result.getData()));
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }


    /**
     * 转派工单
     *
     * @author liheng
     * @author XiaoYunSong <ys.xiao@idiaoyan.com> 新增组织转派功能
     */
    @PostMapping(value = "/transfer")
    public XmResultJson<SimpleIdVO> transferTicket(@RequestBody TransferTicketParam param) {
        if (!ObjectId.isValid(param.getTicketId())) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "工单id不能为空");
        }
        if (StringUtils.isBlank(param.getReason())) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "转派原因不能为空");
        }
        if (Objects.isNull(param.getUserFilter())) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "转派类型不能为空");
        }
        if (FollowerFilterEnum.USER.getIndex().equals(param.getUserFilter())) {
            if (!ObjectId.isValid(param.getUserId())) {
                return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "转派用户id错误");
            }
            if (Objects.isNull(param.getUsername())) {
                return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "转派用户名称不能为空");
            }
        } else if (FollowerFilterEnum.REGION.getIndex().equals(param.getUserFilter())) {
            if (!ObjectId.isValid(param.getRoleId())) {
                return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "转派角色id错误");
            }
            if (!ObjectId.isValid(param.getGroupId())) {
                return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "转派组织id错误");
            }
        } else {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "转派类型错误");
        }

        
         String userId = SecurityContextHolder.getUserId();
        if (StringUtils.equals(param.getUserId(), userId)) {
            return XmResultJson.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "工单不可以转派给本人");
        }

        
        
        String orgId = SecurityContextHolder.getOrgId();
        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        String userName = Constants.BLANK;
        if (Objects.nonNull(tokenDTO)) {
            userName = tokenDTO.getRealName();
        }

        param.setDispatcher(userName);
        param.setDispatcherId(userId);
        param.setOrgId(orgId);

        ServiceResult<SimpleIdVO> result = ticketOperateService.transferTicket(param);
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }


    /**
     * 关闭工单
     *
     * @param param 里面只包含id一个属性
     * @return 关闭的工单的id
     * @author zq.ding <zq.ding@idiaoyan.com>
     * @date 2021/8/20 17:56
     */
    @PostMapping(value = "/close")
    public XmResultJson<SimpleIdVO> closeTicket(@RequestBody SimpleSimpleTicketIdParam param) {
        if (Objects.isNull(param)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, ReqErrorCodeEnum.PARAM_LOST.getMsg());
        }
        String id = param.getTicketId();
        if (!ObjectId.isValid(id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, ReqErrorCodeEnum.PARAM_LOST.getMsg());
        }
        // 关闭原因必填
        if (StringUtils.isBlank(param.getReason())) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, ReqErrorCodeEnum.PARAM_LOST.getMsg());
        }

        
        
        
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        String userName = "";
        if (Objects.nonNull(tokenDTO)) {
            userName = tokenDTO.getRealName();
        }
        // 获取regionName
        String regionName = "";
        List<String> strings = ticketUserGrpcService.listAncestorIdsByUserId(userId);
        if (!CollectionUtils.isEmpty(strings)) {
            String gid = strings.get(0);
            GroupDTO group = ticketBaseUserGrpcService.getGroup(gid);
            if (Objects.nonNull(group)) {
                regionName = group.getTitle();
            }
        }
        if (StrUtil.isBlank(regionName)) {
            regionName = "全国";
        }

        CloseTicketDTO closeTicketDTO = new CloseTicketDTO();
        closeTicketDTO.setOrgId(orgId);
        closeTicketDTO.setUserId(userId);
        closeTicketDTO.setUserName(userName);
        closeTicketDTO.setRegionName(regionName);
        closeTicketDTO.setTicketId(id);
        closeTicketDTO.setReason(param.getReason());
        ServiceResult<SimpleIdVO> serviceResult = ticketOperateService.closeTicket(closeTicketDTO);

        if (serviceResult.isSuccess()) {
            return XmResultJson.success(serviceResult.getData());
        }

        return XmResultJson.fail(serviceResult.getErrorData(), serviceResult.getMsg());
    }


    /**
     * 重新打开工单
     *
     * @param param 里面只包含id一个属性
     * @return 打开工单的id
     * @author zq.ding <zq.ding@idiaoyan.com>
     * @date 2021/8/20 17:56
     */
    @PostMapping(value = "/reopen")
    public XmResultJson<SimpleIdVO> reopenTicket(@RequestBody ReopenTicketParam param) {
        if (Objects.isNull(param)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, ReqErrorCodeEnum.PARAM_LOST.getMsg());
        }
        String id = param.getTicketId();
        if (!ObjectId.isValid(id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, ReqErrorCodeEnum.PARAM_FORMAT.getMsg());
        }
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();
        
        TokenDTO tokenDTO = SecurityContextHolder.getToken();
        String userName = "";
        if (Objects.nonNull(tokenDTO)) {
            userName = tokenDTO.getRealName();
        }
        // 获取regionName
        String regionName = "";
        List<String> strings = ticketUserGrpcService.listAncestorIdsByUserId(userId);
        if (!CollectionUtils.isEmpty(strings)) {
            String gid = strings.get(0);
            GroupDTO group = ticketBaseUserGrpcService.getGroup(gid);
            if (Objects.nonNull(group)) {
                regionName = group.getTitle();
            }
        }
        if (StrUtil.isBlank(regionName)) {
            regionName = "全国";
        }

        param.setOrgId(orgId);
        param.setUserId(userId);
        param.setUserName(userName);
        param.setRegionName(regionName);
        ServiceResult<SimpleIdVO> serviceResult = ticketOperateService.reopenTicket(param);
        if (serviceResult.isSuccess()) {
            return XmResultJson.success(serviceResult.getData());
        }

        return XmResultJson.fail(serviceResult.getErrorData(), serviceResult.getMsg());
    }


    /**
     * 获取下一待处理工单
     *
     * @return 下一个工单的id / 空
     * @author zq.ding <zq.ding@idiaoyan.com>
     * @date 2021/8/20 17:56
     */
    @GetMapping(value = "/next/")
    public XmResultJson<SimpleIdVO> getNextTicket(@ApiParam(value = "工单id", required = true)
                                                  @RequestParam(value = "ticketId") String id) {
        if (StrUtil.isEmpty(id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must endswith ticketId");
        }
        if (!Pattern.matches(RegTypes.OBJECT_ID, id)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "工单id格式错误");
        }
        String orgId = SecurityContextHolder.getOrgId();
        String userId = SecurityContextHolder.getUserId();

        ServiceResult<SimpleIdVO> result = ticketService.nextTicket(id, orgId, userId);
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }

        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }

}
    